import Koa from "koa";
import jwt from "jsonwebtoken";
import { LoginInfo, UserWithPromises } from "../types/user";
import { response } from "../utils/http";
import {
  userAdd,
  userDelByUserIds,
  userFindOne,
  userFindOneByUserId,
  userPage,
  userRoleFindOne,
  userUpdate,
  userUpdateLoginTime,
} from "../servers/user/user";
import roleMiddleware from "../middleware/role";
import { validatorData } from "../db/utils";
import { User } from "../entity/user";
import { menuArrayToTree } from "../servers/menu/utils";
const db = require("../db/mysql");
const Router = require("koa-router");

const router = new Router();

/**
 * @swagger
 * /p-login: #接口访问路径(拼接上之前swagger.js中的host蛇者)
 *   post: #请求方式
 *     summary: 登录  #接口信息
 *     description: 用户登录 #接口描述
 *     tags: [用户] #接口分组
 *     produces:
 *       - application/json
 *     parameters: #传递参数
 *       - name: username #参数名字
 *         description: 用户名 #参数信息
 *         in: formData #参数是存放到请求体中
 *         required: true #是否是必传参数
 *         type: string #参数类型
 *       - name: password
 *         description: 密码
 *         type: string
 *         in: formData
 *         required: true
 *     responses: #返回结果
 *       200:
 *         description: 成功
 */

// 用户登录，返回token
router.post("/p-login", async (ctx: Koa.Context) => {
  let loginInfo: LoginInfo = ctx.request.body as LoginInfo;

  // 验证密码是否为空
  if (!loginInfo.password || !loginInfo.username) {
    ctx.body = response(500, null, "账号或密码不能为空！");
    return false;
  }

  const user = await userFindOne({
    user_name: loginInfo.username,
    password: loginInfo.password,
  });

  // 验证账号密码是否正确
  if (user) {
    if (user.status === "0") {
      ctx.body = response(500, null, "用户已被禁用！");
      return;
    }

    // 修改登录时间
    await userUpdateLoginTime(user.user_id);

    ctx.body = response(
      200,
      jwt.sign(
        { user_id: user.user_id, user_name: user.user_name },
        "suodesinai",
        { expiresIn: "8h" },
      ),
      "ok!",
    );
  } else {
    ctx.body = response(500, null, "用户不存在或账号密码错误！");
  }
});

/**
 * @swagger
 * /user-info: #接口访问路径(拼接上之前swagger.js中的host蛇者)
 *   get: #请求方式
 *     summary: 个人信息 #用户信息接口信息
 *     description: 用户信息 #接口描述
 *     tags: [用户] #接口分组
 *     produces:
 *       - application/json
 *     responses: #返回结果
 *       200:
 *         description: 成功
 */
router.get(
  "/user-info",
  roleMiddleware("user_current_info"),
  async (ctx: Koa.Context) => {
    try {
      let userInfo = ctx.state.user;
      if (userInfo.user_id) {
        const users: UserWithPromises = (await userFindOne({
          user_id: userInfo.user_id,
        })) as unknown as UserWithPromises;

        if (users.status === "0") {
          ctx.body = response(500, null, "用户已禁用！");
          return;
        }

        if (!users) {
          ctx.body = response(500, null, "用户不存在！");
          return;
        }

        // 查询权限和菜单
        const { promises, menuIds, roles } = await userRoleFindOne(
          Number(userInfo.user_id),
        );

        // 赋值所拥有的角色
        users.roles = roles;

        if (promises.length > 0) {
          users.promises = promises;
        }

        // 查询组织
        const orgs = await db(
          `select user_org.user_id,user_org.org_id,org.org_id,org.org_name from user_org left join org on user_org.org_id = org.org_id`,
        );
        users.org = [];
        orgs.forEach(
          (org: { user_id: number; org_name: string; org_id: number }) => {
            if (org.user_id === userInfo.user_id) {
              users.org.push({ org_name: org.org_name, org_id: org.org_id });
            }
          },
        );

        // 查询角色菜单
        let menus = [];
        if (menuIds.length > 0) {
          menus = await db(
            `select * from menu where menu_id in (${menuIds.join(",")})`,
          );
        }
        // 菜单转树(如果没有上下级关系的数据会被过滤掉)
        users.menus = menuArrayToTree(menus);
        ctx.body = response(200, users, "ok！");
      } else {
        ctx.body = response(401, null, "用户不存在！");
      }
    } catch (error) {
      ctx.body = error;
    }
  },
);

/**
 * @swagger
 * /user-page: #接口访问路径
 *   get: #请求方式
 *     summary: 用户分页  #接口信息
 *     description: 获取菜单分页 #接口描述
 *     tags: [用户] #接口分组
 *     produces:
 *       - application/json
 *     parameters: #传递参数
 *       - name: pageIndex #参数名字
 *         description: 页码 #参数信息
 *         in: query #参数是存放到请求体中
 *         required: false #是否是必传参数
 *         type: string #参数类型
 *       - name: pageSize
 *         description: 页数
 *         type: string
 *         in: query
 *         required: false
 *       - name: status
 *         description: 状态 0禁用 、1启用
 *         type: string
 *         in: query
 *         required: false
 *       - name: user_name
 *         description: 用户名
 *         type: string
 *         in: query
 *         required: false
 *       - name: user_nick
 *         description: 昵称
 *         type: string
 *         in: query
 *         required: false
 *     responses: #返回结果
 *       200:
 *         description: 成功
 *         schema:
 *          type: object
 *          properties:
 *              records:
 *                type: array
 *                items:
 *                  type: object
 *                  properties:
 *                    user_id:
 *                      type: integer
 *                      description: 用户id
 *                    username:
 *                      type: string
 *                      description: 账号
 *                    user_nick:
 *                      type: string
 *                      description: 用户昵称
 *                    phone:
 *                      type: string
 *                      description: 手机号码
 *                    email:
 *                      type: string
 *                      description: 邮箱
 *                    sex:
 *                      type: string
 *                      description: 性别 男0 女1
 *                    status:
 *                      type: string
 *                      description: 状态 启用1 禁用0
 *                    create_time:
 *                      type: string
 *                      description: 创建时间
 *              total:
 *                type: integer
 *                properties: 总数
 *       401:
 *         description: 未登录
 */

// 用户分页列表
router.get("/user-page", async (ctx: Koa.Context) => {
  const page = await userPage(ctx.request.query as unknown as any);
  ctx.body = response(200, page, "操作成功！");
});

/**
 * @swagger
 * /user-add: #接口访问路径
 *   post: #请求方式
 *     summary: 添加用户  #接口信息
 *     description: 获取菜单分页 #接口描述
 *     tags: [用户] #接口分组
 *     produces:
 *       - application/json
 *     parameters: #传递参数
 *       - name: user_name #参数名字
 *         description: 用户名/账号 #参数信息
 *         in: formData #参数是存放到请求体中
 *         required: true #是否是必传参数
 *         type: string #参数类型
 *       - name: user_nick
 *         description: 用户昵称
 *         type: string
 *         in: formData
 *         required: true
 *       - name: password
 *         description: 密码
 *         type: string
 *         in: formData
 *         required: true
 *       - name: phone
 *         description: 手机号码
 *         type: string
 *         in: formData
 *         required: false
 *       - name: sex
 *         description: 性别
 *         type: string
 *         in: formData
 *         required: false
 *       - name: status
 *         description: 状态
 *         type: string
 *         in: formData
 *         required: false
 *       - name: roles
 *         description: 所属角色，逗号隔开
 *         type: string
 *         in: formData
 *         required: false
 *       - name: email
 *         description: 邮箱
 *         type: string
 *         in: formData
 *         required: false
 *       - name: remark
 *         description: 备注
 *         type: string
 *         in: formData
 *         required: false
 *     responses: #返回结果
 *       200:
 *         description: 成功
 */
// 添加用户
router.post(
  "/user-add",
  roleMiddleware("user_add"),
  async (ctx: Koa.Context) => {
    const userInfo = ctx.request.body as User;

    await validatorData(userInfo, User);

    const user = await userFindOne({ user_name: userInfo.user_name });

    if (user) {
      ctx.body = response(500, null, `已存在${userInfo.user_name}！`);
      return;
    }

    ctx.body = response(200, await userAdd(userInfo), "操作成功！");
  },
);

/**
 * @swagger
 * /user-update: #接口访问路径
 *   put: #请求方式
 *     summary: 修改用户  #接口信息
 *     description: 获取菜单分页 #接口描述
 *     tags: [用户] #接口分组
 *     produces:
 *       - application/json
 *     parameters: #传递参数
 *       - name: user_id #参数名字
 *         description: 用户id #参数信息
 *         in: formData #参数是存放到请求体中
 *         required: true #是否是必传参数
 *         type: integer #参数类型
 *       - name: user_name #参数名字
 *         description: 用户名/账号 #参数信息
 *         in: formData #参数是存放到请求体中
 *         required: true #是否是必传参数
 *         type: string #参数类型
 *       - name: user_nick
 *         description: 用户昵称
 *         type: string
 *         in: formData
 *         required: true
 *       - name: password
 *         description: 密码
 *         type: string
 *         in: formData
 *         required: true
 *       - name: phone
 *         description: 手机号码
 *         type: string
 *         in: formData
 *         required: false
 *       - name: sex
 *         description: 性别
 *         type: string
 *         in: formData
 *         required: false
 *       - name: status
 *         description: 状态
 *         type: string
 *         in: formData
 *         required: false
 *       - name: roles
 *         description: 所属角色，逗号隔开
 *         type: string
 *         in: formData
 *         required: false
 *       - name: email
 *         description: 邮箱
 *         type: string
 *         in: formData
 *         required: false
 *       - name: remark
 *         description: 备注
 *         type: string
 *         in: formData
 *         required: false
 *     responses: #返回结果
 *       200:
 *         description: 成功
 */
// 修改用户
router.put(
  "/user-update",
  roleMiddleware("user_update"),
  async (ctx: Koa.Context) => {
    const userInfo = ctx.request.body as User;

    if (Number(userInfo.user_id) === 1) {
      ctx.body = response(500, null, `禁止修改该用户！`);
      return;
    }

    await validatorData(userInfo, User);

    const user = await userFindOneByUserId(userInfo.user_id!);

    if (!user) {
      ctx.body = response(500, null, `不存在用户${userInfo.user_id}！`);
      return;
    }

    ctx.body = response(200, await userUpdate(userInfo), "操作成功！");
  },
);

/**
 * @swagger
 * /user-delete: #接口访问路径
 *   delete: #请求方式
 *     summary: 删除用户  #接口信息
 *     description: 获取菜单分页 #接口描述
 *     tags: [用户] #接口分组
 *     produces:
 *       - application/json
 *     parameters: #传递参数
 *       - name: ids #参数名字
 *         description: 用户id，逗号隔开，支持批量删除 #参数信息
 *         in: query #参数是存放到请求体中
 *         required: true #是否是必传参数
 *         type: string #参数类型
 *     responses: #返回结果
 *       200:
 *         description: 成功
 *       401:
 *         description: 未登录
 */
// 删除用户
router.delete(
  "/user-delete",
  roleMiddleware("user_delete"),
  async (ctx: Koa.Context) => {
    const ids = ctx.request.query.ids as string;
    if (!ids) {
      ctx.body = response(500, null, `id不能为空！`);
      return;
    }

    if (ids.split(",").includes("1")) {
      throw new Error("禁止删除该用户！");
    }

    ctx.body = response(200, await userDelByUserIds(ids.split(",")), "ok!");
  },
);

export default router;
